using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.Http;
using System.Web.Http.Controllers;
using System.Web.Http.Filters;
using Sustainalytics.Auth.Claims;

namespace Sustainalytics.Utils
{
    public class InjectUniverseAttribute : ActionFilterAttribute
    {
        private readonly string _parameterName;
        private readonly IList<AccountFeature> _features = new List<AccountFeature> { AccountFeature.CompanySearch };

        public InjectUniverseAttribute(string parameterName, AccountFeature feature = AccountFeature.EsgRatingsOnlineReport)
        {
            _parameterName = parameterName;
            _features.Clear();
            _features.Add(feature);
        }

        public InjectUniverseAttribute(string parameterName, IList<AccountFeature> features)
        {
            _parameterName = parameterName;

            if (features != null && features.Any())
            {
                _features.Clear();
                _features = features;
            }
        }

        /// <exception cref="ArgumentException">No OWIN context found.</exception>
        public override void OnActionExecuting(HttpActionContext actionContext)
        {
            var owinContext = actionContext.Request.GetOwinContext();

            if (owinContext == null)
                throw new ArgumentException("No OWIN context found.");

            var claimsPrincipal = owinContext.Authentication.User;

            if (claimsPrincipal == null || !claimsPrincipal.Identity.IsAuthenticated)
                return;

            //get the parameters from query string
            var queryString = actionContext.Request.GetQueryNameValuePairs().ToList();
            if (queryString.Any())
            {
                var featureKvp = queryString.FirstOrDefault(x => x.Key.Contains("feature"));

                if (!featureKvp.Equals(default(KeyValuePair<string, string>)))
                {
                    _features.Add(!Enum.TryParse(featureKvp.Value, out AccountFeature feature) ? AccountFeature.EsgRatingsOnlineReport : feature);
                }
            }

            var userUniverseIds = claimsPrincipal.Claims.GetUniverseIds(_features);

            actionContext.ActionArguments[_parameterName] = userUniverseIds.ToArray();
        }
    }
}